﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace GwenHelpers.Helpers
{
    public static class QueryableToCsvString
    {
        public static string SimpleElementToCsv<T>(this T item, char separator = ';')
        {
            var properties = typeof(T).GetProperties();
            var line = properties.Where(property => !property.GetGetMethod().IsVirtual).Aggregate(string.Empty, (current, property) => current + ((property.GetValue(item) != null ? (property.GetValue(item)).ToString().Trim() : "NULL") + separator));
            return line.Remove(line.Length - 1);
        }

        /// <summary>
        ///     Méthode non récurrente sérialisant un objet Ienumerable de type générique en XML
        /// </summary>
        /// <typeparam name="T">un type générique</typeparam>
        /// <param name="items">Les items  à serialier sous forme de IEnumerable</param>
        /// <param name="separator">Séparateur utilisé (par défaut ;</param>
        /// <returns>arborescence XML</returns>
        public static string SimpleGenericToCsv<T>(this IEnumerable<T> items, char separator = ';')
        {
            var enumerable = items as T[] ?? items.ToArray();
            var lines = string.Empty;
            lines = typeof(T).GetProperties().Where(property => !property.GetGetMethod().IsVirtual).Aggregate(lines, (current, property) => current + (property.Name + separator));
            lines.Remove(lines.Length - 1);
            return enumerable.Count() == 0 ? lines : enumerable.Aggregate(lines, (current, item) => current + "\t\n" + SimpleElementToCsv(item, separator));
        }

        /// <summary>
        ///     Méthode non récurrente sérialisant un objet Ienumerable de type générique en CSV e l'enregistrant dans unu fichier
        /// </summary>
        /// <typeparam name="T">un type générique</typeparam>
        /// <param name="items">Les items  à serialier sous forme de IEnumerable</param>
        /// <param name="pathFile">le chemin ou écrire le fichier</param>
        /// <param name="separator">Séparateur utilisé (par défaut ;</param>
        /// <returns>arborescence XML</returns>
        public async static Task SimpleGenericToCsvFile<T>(this IEnumerable<T> items, string pathFile, char separator = ';')
        {
            var enumerable = items as T[] ?? items.ToArray();
            var properties = typeof(T).GetProperties();
            var titleLine = properties.Where(property => !property.GetGetMethod().IsVirtual).Aggregate("", (current, property) => current + (property.Name + separator));
            using (TextWriter writer = File.CreateText(pathFile))
            {
                await writer.WriteLineAsync(titleLine.Remove(titleLine.Length - 1));
                if (enumerable.Length == 0) return;
                foreach (var line in items.Select(item => properties.Where(property => !property.GetGetMethod().IsVirtual).Aggregate(string.Empty, (current, property) => current + ((property.GetValue(item) != null ? (property.GetValue(item)).ToString().Trim() : "NULL") + separator))))
                {
                    await writer.WriteLineAsync(line.Remove(line.Length - 1));
                }
            }
        }
    }
}